package com.zm.study.common;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * Created by zoulei
 */
public class DateUtil extends DateUtils {
    private static final Logger LOG = LoggerFactory.getLogger(DateUtil.class);

    public static final int TIMEOUTMILLISECONDS = 12 * 60 * 60 * 1000;
    public static final int TIMEOUTMILLISECONDS1 = 1 * 60 * 60 * 1000;

    public final static String[] parsePatterns = {"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss",
            "yyyy.MM.dd HH:mm", "yyyy.MM", "yyyy-MM-dd HH:mm:ss SSS"};

    public static Date addYear(Date date, int year) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.YEAR, year);// 属性很多也有月等等，可以操作各种时间日期
        return c.getTime();
    }

    public static String formatToSecond(Date date, String s) {
        if (StringUtil.isBlank(s)) {
            s = "yyyyMMddHHmmss";
        }
        java.text.DateFormat format = new java.text.SimpleDateFormat(s);
        return format.format(date);
    }

    public static String formatToStr(Date date, String formatStr) {
        java.text.DateFormat format = new java.text.SimpleDateFormat(formatStr);
        return format.format(date);
    }

    public static String formatToDay(Date date) {
        java.text.DateFormat format = new java.text.SimpleDateFormat("yyyyMMdd");
        return format.format(date);
    }

    public static String formatToDay(Date date, String parse) {
        if (date == null) {
            return "";
        }
        if (StringUtil.isEmpty(parse)) {
            parse = "yyyy-MM-dd";
        }
        java.text.DateFormat format = new java.text.SimpleDateFormat(parse);
        return format.format(date);
    }


    public static String formatToMinute(Date date) {
        java.text.DateFormat format = new java.text.SimpleDateFormat("yyyyMMddHHmm");
        return format.format(date);
    }

    public static String formatToMonth(Date date) {
        java.text.DateFormat format = new java.text.SimpleDateFormat("yyyyMM");
        return format.format(date);
    }

    public static String formatToHour(Date date) {
        java.text.DateFormat format = new java.text.SimpleDateFormat("yyyyMMddHH");
        return format.format(date);
    }

    public static String formatToYear(Date date) {
        java.text.DateFormat format = new java.text.SimpleDateFormat("yyyy");
        return format.format(date);
    }

    public static Date stringSecondToDate(String str) throws ParseException {
        java.text.DateFormat format = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
        return format.parse(str);
    }

    public static Date stringDateToDate(String str) throws ParseException {
        java.text.DateFormat format = new java.text.SimpleDateFormat("yyyyMMdd");
        return format.parse(str);
    }

    public static String stringDateToDateyyyyMMdd(String str) throws ParseException {
        java.text.DateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
        return DateFormatUtils.format(format.parse(str), "yyyy-MM-dd");
    }

    public static Date addDay(Date date, int day) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DAY_OF_YEAR, day);// 属性很多也有月等等，可以操作各种时间日期
        return c.getTime();
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd）
     */
    public static String getDate() {
        return getDate("yyyy-MM-dd");
    }

    public static String getDateMM() {
        return getDate("MM-dd");
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String getDate(String pattern) {
        return DateFormatUtils.format(new Date(), pattern);
    }

    /**
     * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String formatDate(Date date, Object... pattern) {
        String formatDate = null;
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
        }
        return formatDate;
    }

    /**
     * 得到日期时间字符串，转换格式（yyyy-MM-dd HH:mm:ss）
     */
    public static String formatDateTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }
    public static String formatDateTimeSS(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss SSS");
    }

    /**
     * 得到当前时间字符串 格式（HH:mm:ss）
     */
    public static String getTime() {
        return formatDate(new Date(), "HH:mm:ss");
    }

    /**
     * 得到当前时间字符串 格式（HH:mm）
     */
    public static String getHHmm() {
        return formatDate(new Date(), "HH:mm");
    }

    /**
     * 得到当前日期和时间字符串 格式（yyyy-MM-dd HH:mm:ss）
     */
    public static String getDateTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    public static String getDateTimeSSS() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss SSS");
    }

    /**
     * 得到当前年份字符串 格式（yyyy）
     */
    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 获取传入时间到当前日期的年数 四舍五入
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static String getIntervalyear(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return "0";
        }
        double d = getDistanceYearOfTwoDate(startDate, endDate);
        DecimalFormat df = new DecimalFormat("######0.00");
        df.setRoundingMode(RoundingMode.HALF_UP);

        return df.format(d);
    }


    public static Date[] getHalfYear() {
        Date[] dates = new Date[2];

        String year = formatDate(new Date(), "yyyy");
        String str = year + "-07-01";

        java.text.DateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
        try {
            Date d = format.parse(str);

            if (d.compareTo(new Date()) == 0 || d.compareTo(new Date()) == 1) {

                String lastyear = String.valueOf(Integer.valueOf(year) - 1);

                String startDateStr = lastyear + "-07-01";
                dates[0] = format.parse(startDateStr);

                String endDateStr = year + "-01-01";
                dates[1] = format.parse(endDateStr);

            } else {


                String startDateStr = year + "-01-01";
                dates[0] = format.parse(startDateStr);

                String endDateStr = year + "-07-01";
                dates[1] = format.parse(endDateStr);

            }

        } catch (ParseException e) {
            e.printStackTrace();
        }

        return dates;

    }


    /**
     * 得到当前月份字符串 格式（MM）
     */
    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }


    /**
     * 得到当天字符串 格式（dd）
     */
    public static String getDay() {
        return formatDate(new Date(), "dd");
    }


    /**
     * 得到当前星期字符串 格式（E）星期几
     */
    public static String getWeek() {
        return formatDate(new Date(), "E");
    }

    /**
     * 日期型字符串转化为日期 格式 { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss",
     * "yyyy/MM/dd HH:mm", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm" }
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取过去的天数
     *
     * @param date
     * @return
     */
    public static long pastDays(Date date) {

        long t = System.currentTimeMillis() - date.getTime();
        return t / (24 * 60 * 60 * 1000);
    }

    /**
     * 获取过去的小时
     *
     * @param date
     * @return
     */
    public static long pastHour(Date date) {
        long t = System.currentTimeMillis() - date.getTime();
        return t / (60 * 60 * 1000);
    }

    /**
     * 获取过去的分钟
     *
     * @param date
     * @return
     */
    public static long pastMinutes(Date date) {
        long t = System.currentTimeMillis() - date.getTime();
        return t / (60 * 1000);
    }

    /**
     * 转换为时间（天,时:分:秒.毫秒）
     *
     * @param timeMillis
     * @return
     */
    public static String formatDateTime(long timeMillis) {
        long day = timeMillis / (24 * 60 * 60 * 1000);
        long hour = (timeMillis / (60 * 60 * 1000) - day * 24);
        long min = ((timeMillis / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (timeMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        long sss = (timeMillis - day * 24 * 60 * 60 * 1000 - hour * 60 * 60 * 1000 - min * 60 * 1000 - s * 1000);
        return (day > 0 ? day + "," : "") + hour + ":" + min + ":" + s + "." + sss;
    }

    /**
     * 获取两个日期之间的天数
     *
     * @param before
     * @param after
     * @return
     */
    public static double getDistanceOfTwoDate(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
    }

    /**
     * 时间差
     * @param before
     * @param after
     * @return
     */
    public static double getDistanceOfTwoDateString(String before, String after) {
        double difference = 0;
        if (StringUtil.isBlank(before) || StringUtil.isBlank(after)) {
            return difference;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        try {
            difference = getDistanceOfTwoDate(dateFormat.parse(before), dateFormat.parse(after));
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return difference;
    }

    /**
     * 获取两个日期之间的年数
     *
     * @param before
     * @param after
     * @return
     */
    public static double getDistanceYearOfTwoDate(Date before, Date after) {
        double day = DateUtil.getDistanceOfTwoDate(before, after);

        return day / 365;
    }

    /**
     * 毫秒数转日期类型
     *
     * @param timeMillis
     * @return
     */
    public static Date parseDateTime(long timeMillis) {

        if (timeMillis > 0) {
            return new Date(timeMillis);
        }
        return null;

    }

    /**
     * 返回季末时间
     *
     * @param date
     * @return
     */
    public static Date getSeasonTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int array[][] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}};
        int season = 1;
        if (month >= 1 && month <= 3) {
            season = 1;
        }
        if (month >= 4 && month <= 6) {
            season = 2;
        }
        if (month >= 7 && month <= 9) {
            season = 3;
        }
        if (month >= 10 && month <= 12) {
            season = 4;
        }
        // int start_month = array[season-1][0];
        int end_month = array[season - 1][2];

        // int start_days =1;//years+"-"+String.valueOf(start_month)+"-1";//getLastDayOfMonth(years_value,start_month);
        int end_days = getLastDayOfMonth(year, end_month);

        calendar.set(year, end_month - 1, end_days);

        // String seasonDate = year+"-"+start_month+"-"+start_days+";"+year+"-"+end_month+"-"+end_days;
        return calendar.getTime();

    }

    /**
     * 获取某年某月的最后一天
     *
     * @param year  年
     * @param month 月
     * @return 最后一天
     */
    private static int getLastDayOfMonth(int year, int month) {
        if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
            return 31;
        }
        if (month == 4 || month == 6 || month == 9 || month == 11) {
            return 30;
        }
        if (month == 2) {
            if (isLeapYear(year)) {
                return 29;
            } else {
                return 28;
            }
        }
        return 0;
    }

    /**
     * 是否闰年
     *
     * @param year 年
     * @return
     */
    public static boolean isLeapYear(int year) {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }

    /**
     * 毫秒数转日期类型
     *
     * @param timeMillis
     * @return
     */
    public static Date parseDateTime(long timeMillis, String formatstr) {

        if (timeMillis > 0) {
            java.text.DateFormat format = new java.text.SimpleDateFormat(formatstr);

            try {
                Calendar calendar = Calendar.getInstance();
                calendar.setTimeInMillis(timeMillis);

                return calendar.getTime();
            } catch (Exception e) {
                LOG.error("parse error", e);
                return null;
            }
        }
        return null;

    }

    /**
     * 毫秒数转日期类型
     *
     * @param timeMillis
     * @return
     */
    public static String parseDateTimeToStr(long timeMillis, String formatstr) {

        if (formatstr == null || "".equals(formatstr)) {
            formatstr = "yyyy-MM-dd";
        }
        if (timeMillis > 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(timeMillis);

            return DateFormatUtils.format(calendar.getTime(), formatstr);
        }
        return "";

    }


    /**
     * 通过生日计算年龄
     *
     * @param birthDay 生日日期
     * @return 年龄
     */
    public static int getAge(Date birthDay) {
        Calendar cal = Calendar.getInstance();

        if (cal.before(birthDay)) {
            return 0;
        }
        // 当前 年/月/日
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH);
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        cal.setTime(birthDay);
        // 生日 年/月/日
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

        int age = yearNow - yearBirth;

        if (monthNow < monthBirth) {
            age--;
        } else if (monthNow == monthBirth) {
            if (dayOfMonthNow < dayOfMonthBirth) {
                age--;
            }
        }
        return age;
    }

    /**
     * 获取本月第一天日期
     * 格式 yyyy-MM-dd
     *
     * @return
     */
    public static String getFirstDayOfTheMonth() {
        String date = getDate();
        return date.substring(0, 8) + "01";
    }

    /**
     * 获取本年第一天日期
     * 格式 yyyy-MM-dd
     *
     * @return
     */
    public static String getFirstDayOfTheYear() {
        String date = getDate();
        return date.substring(0, 5) + "01-01";
    }

    /**
     * 获取本月第一天时间
     * 格式 yyyy-MM-dd HH:mm:ss SSS
     *
     * @return
     */
    public static String getFirstTimeOfTheMonth() {
        String date = getDate();
        return date.substring(0, 8) + "01 00:00:00 000";
    }

    /**
     * 获取本年第一天时间
     * 格式 yyyy-MM-dd HH:mm:ss SSS
     *
     * @return
     */
    public static String getFirstTimeOfTheYear() {
        String date = getDate();
        return date.substring(0, 5) + "01-01 00:00:00 000";
    }

    /**
     * 返回前n天的日期字符串
     *
     * @return
     */
    public static String getOffsetDay(int days, String date) {
        Calendar cal = Calendar.getInstance();
        try {
            cal.setTime(parseDate(date));
        } catch (Exception e) {
            LOG.error("", e);
            return null;
        }
        cal.add(Calendar.DATE, days);
        return formatDateTime(cal.getTime());
    }

    /**
     * 获取两个日期之间的分钟数
     *
     * @param before
     * @param after
     * @return
     */
    public static long getMinuteOfTwoDate(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (afterTime - beforeTime) / (1000 * 60);
    }

    public static Date strToDateLong(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(strDate, pos);
        return strtodate;
    }


    /**
     * 获取 n年后的今天
     * @param years 正数是n 年后 ,负数是n 年前
     * @return
     */
    public static String getoffsetYear(int years) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.YEAR, years);
        Date y = c.getTime();
        String year = format.format(y);
        return year;
    }

    /**
     * 判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
     *
     * @param nowTime 当前时间
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return
     * @author zm
     */
    public static boolean isEffectiveDate(String nowTime, String startTime, String endTime)  {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            Date nowDate  =dateFormat.parse(nowTime);
            Date startDate  =dateFormat.parse(startTime);
            Date endDate  = dateFormat.parse(endTime);
            if (nowDate.getTime() == startDate.getTime()
                    || nowDate.getTime() == endDate.getTime()) {
                return true;
            }

            Calendar date = Calendar.getInstance();
            date.setTime(nowDate);

            Calendar begin = Calendar.getInstance();
            begin.setTime(startDate);

            Calendar end = Calendar.getInstance();
            end.setTime(endDate);

            if (date.after(begin) && date.before(end)) {
                return true;
            } else {
                return false;
            }
        } catch (ParseException e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * @param args
     * @throws ParseException
     */
    public static void main(String[] args) throws ParseException {
        // System.out.println(formatDate(parseDate("2010/3/6")));
        // System.out.println(getData("yyyy年MM月dd日 E"));
        // long time = new Date().getTime()-parseDate("2012-11-19").getTime();
        // System.out.println(time/(24*60*60*1000));

        // Date date = new Date();
        // Date quarterENdDate = getQuarterInMonth(date);
        //
        // System.out.println("季末:" + quarterENdDate);

        //double day =  DateUtil.getDistanceOfTwoDate( parseDate("2016-04-31"),parseDate("2016-04-01"));

//        long beforeTime = parseDate("2016-04-01").getTime();
//        long afterTime =  parseDate("2016-08-01").getTime();
//        double d   = (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
//
//        double year1 = day/365;
//
//        double year2 = d/365;

//        System.out.println(day);
//        if(day==1){
//            System.out.println("1212");
//
//        }
//
//        System.out.println(getSeasonTime(new Date()));
      /*  System.out.println(getOffsetDay(10, DateUtil.getDateTime()));
        System.out.println(getOffsetDay(10, "2017-12-31"));
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");*/
        String s = DateUtil.getDate();
        //System.out.println(getDistanceOfTwoDate(dateFormat.parse(s), dateFormat.parse("2017-12-21 00:00:00")));

        System.out.println(s.compareTo(DateUtil.getDate()));


        System.out.println(getoffsetYear(-5));


        System.out.println(formatToSecond(getSeasonTime(new Date()), "yyyy-MM-dd HH:mm:ss SSS"));

        String startTime = DateUtil.getDate();

        String endTime = DateUtil.getOffsetDay(1, startTime);
        System.out.println(startTime);
        System.out.println(endTime);
    }

}
